package cn.stylefeng.guns.modular.gridsystem.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.stylefeng.guns.core.annotion.BusinessLog;
import cn.stylefeng.guns.core.context.constant.ConstantContextHolder;
import cn.stylefeng.guns.core.context.login.LoginContextHolder;
import cn.stylefeng.guns.core.enums.LogAnnotionOpTypeEnum;
import cn.stylefeng.guns.core.exception.ServiceException;
import cn.stylefeng.guns.core.pojo.page.PageResult;
import cn.stylefeng.guns.core.pojo.response.ErrorResponseData;
import cn.stylefeng.guns.core.pojo.response.ResponseData;
import cn.stylefeng.guns.core.pojo.response.SuccessResponseData;
import cn.stylefeng.guns.modular.gridsystem.constants.SysRoleConstant;
import cn.stylefeng.guns.modular.gridsystem.entity.*;
import cn.stylefeng.guns.modular.gridsystem.model.param.BizGatewayParam;
import cn.stylefeng.guns.modular.gridsystem.model.param.RegisterParam;
import cn.stylefeng.guns.modular.gridsystem.service.*;
import cn.stylefeng.guns.modular.gridsystem.utils.CollectorConfigUtil;
import cn.stylefeng.guns.modular.gridsystem.utils.EngineUtil;
import cn.stylefeng.guns.modular.gridsystem.utils.MyConst;
import cn.stylefeng.guns.modular.gridsystem.utils.MyFileUtils;
import cn.stylefeng.guns.sys.modular.file.result.SysFileInfoResult;
import cn.stylefeng.guns.sys.modular.file.service.SysFileInfoService;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import cn.stylefeng.guns.modular.gridsystem.model.param.BizFaultModelParam;

import javax.annotation.Resource;
import java.io.File;
import java.util.*;

/**
 * biz_fault_model 控制器
 *
 * @author: ssy
 * @date: 2021/11/01 16:44
 */
@RestController
@Slf4j
public class BizFaultModelController {

    @Resource
    private BizFaultModelService bizFaultModelService;

    @Resource
    private BizStationService bizStationService;

    @Resource
    private BizDeviceService bizDeviceService;

    @Resource
    private BizIndustryInvolvedService bizIndustryInvolvedService;

    @Resource
    private SysFileInfoService sysFileInfoService;

    /**
     * 分页查询biz_fault_model
     *
     * @author ssy
     * @date 2021/11/01 16:44
     */
    @GetMapping("/bizFaultModel/page")
    @BusinessLog(title = "biz_fault_model_分页查询", opType = LogAnnotionOpTypeEnum.QUERY)
    public ResponseData page(BizFaultModelParam bizFaultModelParam) {

        boolean isHasRole = LoginContextHolder.me().hasRole(SysRoleConstant.BUSINESS_MAINTENANCE);
        Set<Integer> set = new HashSet<>();
        PageResult<Map<String, Object>> pageResult = new PageResult<>();

        if(!isHasRole){
            final Long sysLoginUserOrgId = LoginContextHolder.me().getSysLoginUserOrgId();
            final LambdaQueryWrapper<BizStation> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(BizStation::getOrgId, sysLoginUserOrgId);
            final List<BizStation> stationList = bizStationService.list(queryWrapper);
            for (BizStation bizStation:stationList){
                final LambdaQueryWrapper<BizDevice> queryWrapper1 = new LambdaQueryWrapper<>();
                queryWrapper1.eq(BizDevice::getStationId, bizStation.getId());
                final List<BizDevice> deviceList = bizDeviceService.list(queryWrapper1);
                for (BizDevice bizDevice:deviceList){
                    final Integer industryId = bizDevice.getIndustryId();
                    final BizIndustryInvolved industryInvolved = bizIndustryInvolvedService.getById(industryId);
                    if(ObjectUtil.isNotNull(industryInvolved)){
                        final Integer groupId = industryInvolved.getGroupId();
                        set.add(groupId);
                    }
                }
            }
        }
        pageResult = bizFaultModelService.pageList(bizFaultModelParam, set);
        return new SuccessResponseData(pageResult);
    }

    /**
     * 获取全部biz_fault_model
     *
     * @author ssy
     * @date 2021/11/01 16:44
     */
    @GetMapping("/bizFaultModel/list")
    @BusinessLog(title = "biz_fault_model_查询所有", opType = LogAnnotionOpTypeEnum.QUERY)
    public ResponseData list(BizFaultModelParam bizFaultModelParam) {
        return new SuccessResponseData(bizFaultModelService.list(bizFaultModelParam));
    }

    /**
     * 查看详情biz_fault_model
     *
     * @author ssy
     * @date 2021/11/01 16:44
     */
    @GetMapping("/bizFaultModel/detail")
    @BusinessLog(title = "biz_fault_model_查看详情", opType = LogAnnotionOpTypeEnum.DETAIL)
    public ResponseData detail(@Validated(BizFaultModelParam.detail.class) BizFaultModelParam bizFaultModelParam) {
        return new SuccessResponseData(bizFaultModelService.detail(bizFaultModelParam));
    }

    /**
     * 添加biz_fault_model
     *
     * @author ssy
     * @date 2021/11/01 16:44
     */
    @PostMapping("/bizFaultModel/add")
    @BusinessLog(title = "biz_fault_model_增加", opType = LogAnnotionOpTypeEnum.ADD)
    public ResponseData add(@RequestBody @Validated(BizFaultModelParam.add.class) BizFaultModelParam bizFaultModelParam) {
        if (ObjectUtil.isEmpty(bizFaultModelParam.getRegisterStatus())) {
            bizFaultModelParam.setRegisterStatus(0);
        }
        bizFaultModelService.add(bizFaultModelParam);
        return new SuccessResponseData();
    }

    /**
     * 删除biz_fault_model
     *
     * @author ssy
     * @date 2021/11/01 16:44
     */
    @PostMapping("/bizFaultModel/delete")
    @BusinessLog(title = "biz_fault_model_删除", opType = LogAnnotionOpTypeEnum.DELETE)
    public ResponseData delete(@RequestBody @Validated(BizFaultModelParam.delete.class) BizFaultModelParam bizFaultModelParam) {
        bizFaultModelService.delete(bizFaultModelParam);
        return new SuccessResponseData();
    }

    /**
     * 编辑biz_fault_model
     *
     * @author ssy
     * @date 2021/11/01 16:44
     */
    @PostMapping("/bizFaultModel/edit")
    @BusinessLog(title = "biz_fault_model_编辑", opType = LogAnnotionOpTypeEnum.EDIT)
    public ResponseData edit(@RequestBody @Validated(BizFaultModelParam.edit.class) BizFaultModelParam bizFaultModelParam) {
        bizFaultModelService.edit(bizFaultModelParam);
        return new SuccessResponseData();
    }

    /**
     * 注册模型
     *
     * @param registerParam
     * @return
     */
    @PostMapping("/bizFaultModel/registerModel")
    public JSONObject register(RegisterParam registerParam) {
        String filePath = registerParam.getFilePath();
        String[] split = filePath.split(",");
        File[] files = new File[split.length];
        Map<String, Object> map = Maps.newHashMap();
        for (int i = 0; i < split.length; i++) {
            String path = MyFileUtils.getUploadPath() + "/" + split[i];
            File file = FileUtil.file(path);
            boolean exists = file.exists();
            if (!exists) {
                map.put("code", 500);
                map.put("message", "文件不存在");
                log.info(map.toString());
                return JSONUtil.parseObj(map);
            } else {
                files[i] = file;
            }
        }
        String post = EngineUtil.register(registerParam.getAccessToken(), registerParam.getGroupId(), files);
        return JSONUtil.parseObj(post);
    }
    /**
     * 批量注册模型
     *
     * @param registerParam
     * @return
     */
    @PostMapping("/bizFaultModel/batchRegisterModel")
    public ResponseData batchRegister(RegisterParam registerParam) {
        String filePath = registerParam.getFilePath();
        String[] split = filePath.split(",");

        Map<String, List<File>> fileMap = new HashMap<>();
        Map<String, List<String>> pathMap = new HashMap<>();

        for (String path : split) {
            String fullPath = MyFileUtils.getUploadPath() + "/" + path;
            File file = FileUtil.file(fullPath);
            if (!file.exists()) {
                throw new ServiceException("文件不存在");
            }
            String fileOrgName = path.split("\\/")[1];
            if (fileOrgName.split("-").length != 2) {
                throw new ServiceException("文件名不合法，请使用形如17003-1.wav再试");
            }
            String key = fileOrgName.split("-")[0];
            fileMap.computeIfAbsent(key, k -> new ArrayList<>()).add(file);
            pathMap.computeIfAbsent(key, k -> new ArrayList<>()).add(path);
        }

        List<BizFaultModel> list = bizFaultModelService.list();
        StringBuilder msgSuc = new StringBuilder();
        StringBuilder msgFal = new StringBuilder();
        StringBuilder msgNotFound = new StringBuilder();

        if (list != null && !list.isEmpty()) {
            for (BizFaultModel model : list) {
                if (fileMap.containsKey(model.getAccessToken())) {
                    List<File> fileList = fileMap.get(model.getAccessToken());
                    File[] files = fileList.toArray(new File[0]);

                    String post = EngineUtil.register(model.getAccessToken(), String.valueOf(model.getGroupId()), files);
                    JSONObject jsonObject = JSONUtil.parseObj(post);
                    if (jsonObject.getStr("code").equals("200")) {
                        model.setRegisterStatus(1);
                        model.setModelFile(String.join(",", pathMap.get(model.getAccessToken())));
                        bizFaultModelService.updateById(model);
                        msgSuc.append(model.getAccessToken()).append(",");
                    } else {
                        msgFal.append(model.getAccessToken()).append(",");
                    }
                }
            }
        }

        for (String key : fileMap.keySet()) {
            boolean isExist = list.stream().anyMatch(model -> key.equals(model.getAccessToken()));
            if (!isExist) {
                msgNotFound.append(key).append(",");
            }
        }

        StringBuilder msg = new StringBuilder();
        if (msgSuc.length() > 0) {
            msg.append("注册成功的编号为：").append(msgSuc.deleteCharAt(msgSuc.length() - 1));
        }
        if (msgFal.length() > 0) {
            msg.append("；\r\n失败的编号为：").append(msgFal.deleteCharAt(msgFal.length() - 1));
        }
        if (msgNotFound.length() > 0) {
            msg.append("；\r\n库中不存在的编号为:").append(msgNotFound.deleteCharAt(msgNotFound.length() - 1));
        }

        return new SuccessResponseData(msg.toString());
    }


    @GetMapping("/bizFaultModel/getBizFaultModel")
    public ResponseData getBizFaultModel(BizFaultModelParam bizFaultModelParam) {
        QueryWrapper<BizFaultModel> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("fault_name", bizFaultModelParam.getFaultName());
        queryWrapper.last("limit 1");
        return ResponseData.success(bizFaultModelService.getOne(queryWrapper));
    }

    /**
     * 注册采集端模型
     *
     * @param registerParam
     * @return
     */
    @PostMapping("/bizFaultModel/registerCollectModel")
    public ResponseData registerCollectModel(RegisterParam registerParam) {
        String collectUrl = "http://" + registerParam.getCollectoeIp() + ":8888";
        String fileIds = registerParam.getFileIds();
        String[] split = fileIds.split(",");
        File[] files = new File[split.length];
        for (int i = 0; i < split.length; i++) {
            SysFileInfoResult fileInfoResult = sysFileInfoService.getFileInfoResult(Long.valueOf(split[i]));
            String path = MyFileUtils.getUploadPath() + "/" + fileInfoResult.getFileBucket() + "/" + fileInfoResult.getFileObjectName();
            File file = FileUtil.file(path);
            boolean exists = file.exists();
            if (!exists) {
                return new ErrorResponseData(500, "文件不存在");
            } else {
                files[i] = file;
            }
        }

        String post = CollectorConfigUtil.register(collectUrl, registerParam.getAccessToken(), registerParam.getGroupId(), files);
        JSONObject parseObj = JSONUtil.parseObj(post);
        log.info("采集端注册模型结果：{}", post);
        if (parseObj.get("code").equals("200")) {
            return new SuccessResponseData();
        } else {
            return new ErrorResponseData(500, "采集端注册模型失败");
        }

    }

}
